#include "treemodel.h"

#include <QBrush>
#include <QFont>

TreeModel::TreeModel(QObject *parent)
    : QAbstractItemModel(parent) {
    int values[N]={36,10,26,3,7, 11,15, 1,2,3,4,5,6,7,8};
    for (int i=0; i<N; i++)
        numbers[i] = values[i];
    m_timer.setInterval(1000);
    connect(&m_timer, &QTimer::timeout, this, [=]() {
        numbers[14]++;
        numbers[6] = numbers[14]+numbers[13];
        numbers[2] = numbers[5]+numbers[6];
        numbers[0] = numbers[1]+numbers[2];

        QModelIndex idx_14 = createIndex(1, 0, 14);
        QModelIndex idx_6 = createIndex(1, 0, 6);
        QModelIndex idx_2 = createIndex(1, 0, 2);
        QModelIndex idx_0 = createIndex(0, 0, (int)0);

        emit dataChanged(idx_14, idx_14);
        emit dataChanged(idx_6, idx_6);
        emit dataChanged(idx_2, idx_2);
        emit dataChanged(idx_0, idx_0);
    });
    m_timer.start();
}


int TreeModel::rowCount(const QModelIndex &parent) const
{
    if(!parent.isValid())
        return 1;
    if(parent.internalId() < N/2)
        return 2;
    else
        return 0;
}

int TreeModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return 1;
}

QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
{
    if(!parent.isValid())
        return createIndex(row, column, nullptr);
    int parent_idx = parent.internalId();
    int idx = parent_idx*2 + (row+1);
    return createIndex(row, column, idx);
}

QModelIndex TreeModel::parent(const QModelIndex &index) const
{
    if(index.internalId() == 0)
        return QModelIndex();
    int parent_idx = (index.internalId() -1)/2;
    return createIndex((parent_idx+1)%2, 0, parent_idx);
}

QVariant TreeModel::data(const QModelIndex &index, int role) const
{
    switch (role) {
    case Qt::DisplayRole:
    case Qt::EditRole:
        return numbers[index.internalId()];
    case Qt::ForegroundRole:
        return index.internalId() >= N / 2 ? QBrush(Qt::red) : QVariant();
    case Qt::FontRole:
        return index.internalId() < N / 2 ? QFont("Microsoft YaHei", 26) : QVariant();
    default:
        break;
    }

    return QVariant();
}

QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role == Qt::DisplayRole && section == 0 && orientation == Qt::Horizontal) {
        return "Full Binary Tree";
    }
    return QVariant();
}

Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
    if(index.internalId() < N / 2) {
        return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
    }
    else {
        return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
    }
}

bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(role != Qt::EditRole) return true;
    int id = index.internalId();
    while(true) {
        if(id >= N/2 ) {
            numbers[id] = value.toInt();
        }
        else {
            numbers[id] = numbers[2*id+1] + numbers[2*id+2];
        }
        QModelIndex idx = createIndex(1, 0, id);
        emit dataChanged(idx, idx);
        if(id == 0)
            break;
        id = (id-1)/2;
    }

    return true;
}
